package module

import (
	"fmt"
	"my_im2/server/_interface"
	"strings"
)

type BusinessModule struct {
	server _interface.Server
}

func NewBusinessModule(server _interface.Server) *BusinessModule {
	return &BusinessModule{
		server: server,
	}
}

func (b *BusinessModule) HandleMsg(id uint, msg string) {
	b.server.GetLogger().LogInfo(fmt.Sprintf("[收到消息] (%d) %s", id, msg))

	tokens := strings.Split(msg, "|")
	if len(tokens) == 0 {
		return
	}

	cmd := tokens[0]
	if f, ok := handleFuncMap[cmd]; ok {
		f(b, id, msg)
	} else {
		b.server.GetLogger().LogInfo(fmt.Sprintf("[未知消息] (%d) %s", id, msg))
	}
}

type handleFunc func(b *BusinessModule, id uint, msg string)

var handleFuncMap = make(map[string]handleFunc)

func init() {
	handleFuncMap["signin"] = onSignIn
	handleFuncMap["signup"] = onSignUp
	handleFuncMap["addfriend"] = onAddFriend
	handleFuncMap["delfriend"] = onDelFriend
	handleFuncMap["getfriendstatus"] = onGetFriendStatus
	handleFuncMap["creategroup"] = onCreateGroup
	handleFuncMap["joingroup"] = onJoinGroup
	handleFuncMap["exitgroup"] = onExitGroup
	handleFuncMap["usermsg"] = onUserMsg
	handleFuncMap["groupmsg"] = onGroupMsg
	handleFuncMap["removeaccount"] = onRemoveAccount
}

//用户注册
func onSignIn(b *BusinessModule, id uint, msg string) {
	okMsg := "signinok"
	failMsg := "signinfail"

	//检查格式
	tokens := strings.Split(msg, "|")
	if len(tokens) != 3 {
		b.server.SendMsgToId(id, failMsg+"|注册格式错误")
		return
	}

	//提取参数
	user := tokens[1]
	passwd := tokens[2]

	//检查参数
	if user == "" || passwd == "" {
		b.server.SendMsgToId(id, failMsg+"|用户名与密码不能为空")
		return
	}

	//判断用户是否已注册
	if b.server.GetDb().IsUserExist(user) {
		b.server.SendMsgToId(id, failMsg+"|该用户已经注册")
		return
	}

	//执行注册
	b.server.GetDb().AddUser(user, passwd)

	b.server.GetLogger().LogInfo(fmt.Sprintf("[注册新用户] user=%s,passwd=%s", user, passwd))

	//返回消息-注册成功
	b.server.SendMsgToId(id, okMsg)

	//立即登录
	onSignUp(b, id, fmt.Sprintf("signup|%s|%s", user, passwd))
}

//用户登录
func onSignUp(b *BusinessModule, id uint, msg string) {
	okMsg := "signupok"
	failMsg := "signupfail"

	//检查格式
	tokens := strings.Split(msg, "|")
	if len(tokens) != 3 {
		b.server.SendMsgToId(id, failMsg+"|登录格式错误")
		return
	}

	//提取参数
	user := tokens[1]
	passwd := tokens[2]

	//执行登录
	err := b.server.GetDb().Login(id, user, passwd)
	if err != nil {
		/*登录失败*/
		b.server.SendMsgToId(id, failMsg+"|"+err.Error())
		return
	}
	/*登录成功*/
	//返回消息
	b.server.SendMsgToId(id, okMsg+"|"+user)
	//通知好友上线
	b.server.NotifyFriendOnline(user)

	b.server.GetLogger().LogInfo(fmt.Sprintf("[登录] %s", user))
}

//添加好友
func onAddFriend(b *BusinessModule, id uint, msg string) {
	okMsg := "addfriendok"
	failMsg := "addfriendfail"

	//检查登录状态
	if !b.server.GetDb().IsConnLogined(id) {
		b.server.SendMsgToId(id, failMsg+"|你没有登录")
		return
	}

	//检查格式
	tokens := strings.Split(msg, "|")
	if len(tokens) != 2 {
		b.server.SendMsgToId(id, failMsg+"|添加好友格式错误")
		return
	}

	//提取参数
	user := tokens[1]

	//检查用户是否存在
	if !b.server.GetDb().IsUserExist(user) {
		b.server.SendMsgToId(id, failMsg+"|用户不存在")
		return
	}

	//获取自己的用户名
	me, ok := b.server.GetDb().GetConnUser(id)
	if !ok {
		return
	}

	//不能添加自己
	if me == user {
		b.server.SendMsgToId(id, failMsg+"|不能添加自己为好友")
		return
	}

	//判断是否已经添加
	if b.server.GetDb().IsUserHasFriend(me, user) {
		b.server.SendMsgToId(id, failMsg+"|"+user+"已经是你的好友了")
		return
	}

	//执行添加
	b.server.GetDb().AddUserFriend(me, user)

	//返回消息
	b.server.SendMsgToId(id, okMsg)

	b.server.GetLogger().LogInfo(fmt.Sprintf("[添加好友] %s 添加 %s", me, user))
}

//删除好友
func onDelFriend(b *BusinessModule, id uint, msg string) {
	okMsg := "delfriendok"
	failMsg := "delfriendfail"

	//检查登录状态
	if !b.server.GetDb().IsConnLogined(id) {
		b.server.SendMsgToId(id, failMsg+"|你没有登录")
		return
	}

	//检查格式
	tokens := strings.Split(msg, "|")
	if len(tokens) != 2 {
		b.server.SendMsgToId(id, failMsg+"|添加好友格式错误")
		return
	}

	//提取参数
	user := tokens[1]

	//获取自己的用户名
	me, ok := b.server.GetDb().GetConnUser(id)
	if !ok {
		return
	}

	//判断是否已经添加
	if !b.server.GetDb().IsUserHasFriend(me, user) {
		b.server.SendMsgToId(id, failMsg+"|"+user+"不是你的好友")
		return
	}

	//执行删除
	b.server.GetDb().DelUserFriend(me, user)

	//返回消息
	b.server.SendMsgToId(id, okMsg)

	b.server.GetLogger().LogInfo(fmt.Sprintf("[删除好友] %s 删除 %s", me, user))
}

//查询好友在线情况
func onGetFriendStatus(b *BusinessModule, id uint, msg string) {
	okMsg := "friendstatus"
	failMsg := "getfriendstatusfail"

	//检查登录状态
	if !b.server.GetDb().IsConnLogined(id) {
		b.server.SendMsgToId(id, failMsg+"|你没有登录")
		return
	}

	//获取自己的用户名
	me, ok := b.server.GetDb().GetConnUser(id)
	if !ok {
		return
	}

	//查询数据库
	onlineFriends, offlineFriends := b.server.GetDb().GetMyFriendsOnlineStatus(me)

	//返回数据
	res := fmt.Sprintf("%s|%s|%s", okMsg, strings.Join(onlineFriends, ","), strings.Join(offlineFriends, ","))
	b.server.SendMsgToId(id, res)

	b.server.GetLogger().LogInfo(fmt.Sprintf("[查询好友在线情况] 查询人：%s，返回：%s", me, res))
}

//创建群聊
func onCreateGroup(b *BusinessModule, id uint, msg string) {
	okMsg := "creategroupok"
	failMsg := "creategroupfail"

	//检查登录状态
	if !b.server.GetDb().IsConnLogined(id) {
		b.server.SendMsgToId(id, failMsg+"|你没有登录")
		return
	}

	//检查格式
	tokens := strings.Split(msg, "|")
	if len(tokens) != 2 {
		b.server.SendMsgToId(id, failMsg+"|创建群聊格式错误")
		return
	}

	//提取参数
	group := tokens[1]

	//检查群聊是否存在
	if b.server.GetDb().IsGroupExist(group) {
		b.server.SendMsgToId(id, failMsg+"|该群聊已存在")
		return
	}

	//获取自己的用户名
	me, ok := b.server.GetDb().GetConnUser(id)
	if !ok {
		return
	}

	//创建群聊
	b.server.GetDb().AddGroup(group)

	//自己加入群聊
	b.server.GetDb().AddGroupMember(group, me)

	//返回消息
	b.server.SendMsgToId(id, okMsg)

	b.server.GetLogger().LogInfo(fmt.Sprintf("[创建群聊] %s 创建了群 %s", me, group))
}

//加入群聊
func onJoinGroup(b *BusinessModule, id uint, msg string) {
	okMsg := "joingroupok"
	failMsg := "joingroupfail"

	//检查登录状态
	if !b.server.GetDb().IsConnLogined(id) {
		b.server.SendMsgToId(id, failMsg+"|你没有登录")
		return
	}

	//检查格式
	tokens := strings.Split(msg, "|")
	if len(tokens) != 2 {
		b.server.SendMsgToId(id, failMsg+"|加入群聊格式错误")
		return
	}

	//提取参数
	group := tokens[1]

	//检查群聊是否存在
	if !b.server.GetDb().IsGroupExist(group) {
		b.server.SendMsgToId(id, failMsg+"|群聊不存在")
		return
	}

	//获取自己的用户名
	me, ok := b.server.GetDb().GetConnUser(id)
	if !ok {
		return
	}

	//检查自己是否已加入该群聊
	if b.server.GetDb().IsGroupHasMember(group, me) {
		b.server.SendMsgToId(id, failMsg+"|你已加入该群聊")
		return
	}

	//自己加入群聊
	b.server.GetDb().AddGroupMember(group, me)

	//返回消息
	b.server.SendMsgToId(id, okMsg)

	b.server.GetLogger().LogInfo(fmt.Sprintf("[加入群聊] %s 加入了群 %s", me, group))
}

//退出群聊
func onExitGroup(b *BusinessModule, id uint, msg string) {
	okMsg := "exitgroupok"
	failMsg := "exitgroupfail"

	//检查登录状态
	if !b.server.GetDb().IsConnLogined(id) {
		b.server.SendMsgToId(id, failMsg+"|你没有登录")
		return
	}

	//检查格式
	tokens := strings.Split(msg, "|")
	if len(tokens) != 2 {
		b.server.SendMsgToId(id, failMsg+"|退出群聊格式错误")
		return
	}

	//提取参数
	group := tokens[1]

	//获取自己的用户名
	me, ok := b.server.GetDb().GetConnUser(id)
	if !ok {
		return
	}

	//检查自己是否已加入该群聊
	if !b.server.GetDb().IsGroupHasMember(group, me) {
		b.server.SendMsgToId(id, failMsg+"|你不在该群聊中")
		return
	}

	//退出该群聊
	b.server.GetDb().DelGroupMember(group, me)

	//返回消息
	b.server.SendMsgToId(id, okMsg)

	b.server.GetLogger().LogInfo(fmt.Sprintf("[退出群聊] %s 退出了群 %s", me, group))

	//如果该群中没有成员了，则删除该群
	if b.server.GetDb().TryCleanGroup(group) {
		b.server.GetLogger().LogInfo(fmt.Sprintf("[销毁群聊] %s", group))
	}
}

//私聊
func onUserMsg(b *BusinessModule, id uint, msg string) {
	failMsg := "usermsgfail"

	//检查登录状态
	if !b.server.GetDb().IsConnLogined(id) {
		b.server.SendMsgToId(id, failMsg+"|你没有登录")
		return
	}

	//检查格式
	tokens := strings.Split(msg, "|")
	if len(tokens) != 3 {
		b.server.SendMsgToId(id, failMsg+"|私聊格式错误")
		return
	}

	//提取参数
	user := tokens[1]
	content := tokens[2]

	//检查用户是否存在
	if !b.server.GetDb().IsUserExist(user) {
		b.server.SendMsgToId(id, failMsg+"|用户不存在")
		return
	}

	//判断是否在线
	if !b.server.GetDb().IsUserLogined(user) {
		b.server.SendMsgToId(id, failMsg+"|用户不在线")
		return
	}

	//获取自己的用户名
	me, ok := b.server.GetDb().GetConnUser(id)
	if !ok {
		return
	}

	//发送消息
	b.server.SendMsgToUser(user, fmt.Sprintf("recvusermsg|%s|%s", me, content))

	b.server.GetLogger().LogInfo(fmt.Sprintf("[私聊] %s -> %s : %s", me, user, content))
}

//群聊
func onGroupMsg(b *BusinessModule, id uint, msg string) {
	failMsg := "groupmsgfail"

	//检查登录状态
	if !b.server.GetDb().IsConnLogined(id) {
		b.server.SendMsgToId(id, failMsg+"|你没有登录")
		return
	}

	//检查格式
	tokens := strings.Split(msg, "|")
	if len(tokens) != 3 {
		b.server.SendMsgToId(id, failMsg+"|群聊格式错误")
		return
	}

	//提取参数
	group := tokens[1]
	content := tokens[2]

	//判断该群是否存在
	if !b.server.GetDb().IsGroupExist(group) {
		b.server.SendMsgToId(id, failMsg+"|群不存在")
		return
	}

	//获取自己的用户名
	me, ok := b.server.GetDb().GetConnUser(id)
	if !ok {
		return
	}

	//发送群聊消息
	b.server.SendMsgToGroup(group, fmt.Sprintf("recvgroupmsg|%s|%s|%s", group, me, content))

	b.server.GetLogger().LogInfo(fmt.Sprintf("[群聊] %s -> %s : %s", me, group, content))
}

//删除账号
func onRemoveAccount(b *BusinessModule, id uint, msg string) {
	okMsg := "removeaccountok"
	failMsg := "removeaccountfail"

	//检查登录状态
	if !b.server.GetDb().IsConnLogined(id) {
		b.server.SendMsgToId(id, failMsg+"|你没有登录")
		return
	}

	//获取自己的用户名
	me, ok := b.server.GetDb().GetConnUser(id)
	if !ok {
		return
	}

	//通知好友下线
	b.server.NotifyFriendOffline(me)

	//me退出所有群
	b.server.GetDb().UserExitAllGroup(me)

	//从用户好友中删除me
	b.server.GetDb().DelMeFromAllUsers(me)

	//删除我的数据
	b.server.GetDb().DelUser(me)

	//重置当前conn
	b.server.GetDb().ConnLogout(me)

	//返回消息
	b.server.SendMsgToId(id, okMsg)

	b.server.GetLogger().LogInfo(fmt.Sprintf("[注销用户] %s", me))
}
